package com.fw.system.web.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaRunStepInfo;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fw.common.Builder;
import com.fw.common.IdXD;
import com.fw.mes.Result;
import com.fw.system.web.dao.TbUserMapper;
import com.fw.system.web.model.entity.*;
import com.fw.system.web.model.form.WechatForm;
import com.fw.system.web.model.form.WechatInfoForm;
import com.fw.system.web.model.vo.FootCityVo;
import com.fw.system.web.model.vo.UserCodeVo;
import com.fw.system.web.service.*;
import com.fw.utils.AuthUtils;
import com.fw.utils.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

import static com.fw.mes.ResultUtils.success;

/**
 * <p>
 * 客户端用户表 服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-03-28
 */
@Service
@Slf4j
public class TbUserServiceImpl extends ServiceImpl<TbUserMapper, TbUser> implements ITbUserService {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private AuthUtils authUtils;

    @Autowired
    private IdXD idXD;

    @Autowired
    private ITbWechatFootService footService;
    @Autowired
    private ITbUserService userService;
    @Autowired
    private ITbSysRuleService ruleService;
    @Autowired
    private ITbCityCodeService cityCodeService;
    @Autowired
    private ITbUserCityJoinService joinService;
    @Autowired
    private ITbNoticeService noticeService;

    @Override
    public Result<UserCodeVo> loginByCode(String code) {
        UserCodeVo userCodeVo = new UserCodeVo();
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(code);
            TbUser tbUser = getOne(Wrappers.<TbUser>lambdaQuery().eq(TbUser::getOpenId, session.getOpenid()));
            if (Objects.nonNull(tbUser)) {
                userCodeVo.setToken(authUtils.createJWT(tbUser.getId(), JsonUtils.objectToJson(tbUser), null));
                userCodeVo.setWxMaJscode2SessionResult(session);
                return success(userCodeVo);
            }
            log.info(session.getSessionKey());
            log.info(session.getOpenid());
            userCodeVo.setWxMaJscode2SessionResult(session);
            return success(userCodeVo);
        } catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public String login(WechatForm wechatForm) {
        //   WxMaUserInfo userInfo = wxMaService.getUserService().getUserInfo(wechatInfoForm.getSessionKey(), wechatInfoForm.getEncryptedData(), wechatInfoForm.getIv());
        String openId = wechatForm.getOpenId();
        // 判定,是否是二次用户
        TbUser tbUser = getOne(Wrappers.<TbUser>lambdaQuery().eq(TbUser::getOpenId, openId));
        if (Objects.nonNull(tbUser)) {
            return authUtils.createJWT(tbUser.getId(), JsonUtils.objectToJson(tbUser), null);
        }
        String userId = idXD.nextId();
        tbUser = new TbUser(wechatForm, userId);
        tbUser.setInviteCode(checkRandom(RandomUtil.randomString(8)));
        save(tbUser);
        return authUtils.createJWT(tbUser.getId(), JsonUtils.objectToJson(tbUser), null);
    }

    private String checkRandom(String randomString) {
        if (userService.getOne(Wrappers.<TbUser>lambdaQuery().eq(TbUser::getIntegral, randomString)) == null)
            return randomString;
        return RandomUtil.randomString(8);
    }


    @Override
    public FootCityVo runData(TbUser user, WechatInfoForm wechatInfoForm) {

        FootCityVo footCityVo = new FootCityVo();
        List<WxMaRunStepInfo> maRunStepInfos = wxMaService.getRunService().getRunStepInfo(wechatInfoForm.getSessionKey(), wechatInfoForm.getEncryptedData(), wechatInfoForm.getIv());
        // 获取今天的步数
        WxMaRunStepInfo wxMaRunStepInfo = ListUtil.reverse(maRunStepInfos).get(0);
        Integer step = wxMaRunStepInfo.getStep();

        TbSysRule dayFoolRue = ruleService.getById(15);
        TbSysRule boFool = ruleService.getById(12);
        footCityVo.setCountStep(Integer.parseInt(dayFoolRue.getRuleValue()));
        TbWechatFoot foot = footService.getOne(Wrappers.<TbWechatFoot>lambdaQuery().eq(TbWechatFoot::getUserId, user.getId())
                .last("and to_days(create_time) = to_days(now())"));
        //计算出今日被炸掉的步数
        int size = noticeService.list(Wrappers.<TbNotice>lambdaQuery().eq(TbNotice::getIsState, 0).eq(TbNotice::getNoticeType, 1)
                .eq(TbNotice::getGamePlayerUserId, user.getId()).last("and to_days(create_time) = to_days(now())")).size();
        int i1 = Integer.parseInt(boFool.getRuleValue()) * size;

        step = step - i1;
        if (foot == null) {
            Builder.of(TbWechatFoot::new)
                    .with(TbWechatFoot::setId, idXD.nextId())
                    .with(TbWechatFoot::setCreateTime, LocalDateTime.now())
                    .with(TbWechatFoot::setGainTime, LocalDateTime.now().toString())
                    .with(TbWechatFoot::setWechatFoot, step)
                    .with(TbWechatFoot::setUserId, user.getId()).build().insert();
        } else {
            int i = Integer.parseInt(dayFoolRue.getRuleValue());
            if (step > i)
                step = i;
            if (step < 0)
                step = 0;
            footService.updateById(foot.setWechatFoot(step));
        }
        //更新用户表今日步数字段和总步数字段

        user.setWechatFool(step);
        //更新用户总累计步数字段
        QueryWrapper<TbWechatFoot> select = new QueryWrapper<TbWechatFoot>().select("sum(wechat_foot) As wechatFoot ");
        select.eq("user_id", user.getId());
        user.setCountFool(footService.getOne(select).getWechatFoot()).updateById();
        String ruleValue = ruleService.getById(10).getRuleValue();
        if (user.getCountFool() >= Integer.parseInt(ruleValue) * (user.getNowCityCount() + 1)) {
            //验证今日解锁
            TbUserCityJoin cityJoin = joinService.getOne(Wrappers.<TbUserCityJoin>lambdaQuery().eq(TbUserCityJoin::getUserId, user.getId())
                    .eq(TbUserCityJoin::getIsType, 2).last("and to_days(create_time) = to_days(now())"));
            if (cityJoin == null) {
                if (user.getNowCityCount() < 10) {
                    TbCityCode one = cityCodeService.getOne(Wrappers.<TbCityCode>lambdaQuery().eq(TbCityCode::getSortCode, user.getNowCityCount() + 1));
                    if (one != null) {
                        Builder.of(TbUserCityJoin::new)
                                .with(TbUserCityJoin::setCreateTime, LocalDateTime.now())
                                .with(TbUserCityJoin::setId, idXD.nextId())
                                .with(TbUserCityJoin::setIsType, 2)
                                .with(TbUserCityJoin::setCityCode, one.getId())
                                .with(TbUserCityJoin::setUserId, user.getId()).build().insert();
                        user.setNowCityCount(user.getNowCityCount() + 1).updateById();
                        footCityVo.setCityName(one.getCityName());
                        footCityVo.setCityImg(one.getCityImg());
                        footCityVo.setSortCode(one.getSortCode());
                    }
                }
            }

        }
        footCityVo.setFool(user.getWechatFool());
        return footCityVo;
    }

}
